/***   node 公共处理函数              */
const fs = require('fs'),
    util = require('util')
//  打印对象
exports.pobj = (data,all) =>{
    var xhtml = ''
    if(typeof(data) == 'object'){
        for(var k in data){
            if(typeof(data[k]) != 'object' && typeof(data[k]) != 'function') xhtml += `<li>${k} : ${data[k]}</li>`
            else if(all) xhtml += `<li><br>${k} : ${data[k]}</li>`
        }
    }
    return xhtml
}
//  清除模块缓存
exports.clear = (opt) =>{
    if(typeof(opt) == 'undefined') opt = [__dirname]
    else if(typeof(opt) == 'string') opt = [opt]
    else if(typeof(opt) != 'object') return false
    for(var k in opt){
        try{
            delete require.cache[require.resolve(opt[k])]
        }catch(e){}
    }
}
//  日期处理
exports.date = (format) =>{
    var d = new Date()
    var tpl = {
        'Y':d.getFullYear(),
        'M':d.getMonth()+1,
        'D':d.getDate(),
        'H':d.getHours(),
        'i':d.getMinutes(),
        's':d.getSeconds()
    }
    if(!format) return `${tpl['Y']}-${tpl['M']}-${tpl['D']} ${tpl['H']}:${tpl['i']}:${tpl['s']}`
    else{
        var str = format
        for(var k in tpl){
            if(str.indexOf(k)>-1) str = str.replace(new RegExp(k,'g'),String(tpl[k]))
        }
        return str
    }
}
//  引入模块(同一module目录下)
exports.require = (file) =>{
    return require(`${__dirname}/${file}.js`)
}
// loacal/global 为Windows系统下无法用 require 加载的模块函数补丁
exports.local = (file) => {
    var sys = conf('sys'),
        prefix
    if(sys && sys.local) prefix = sys.local
    else prefix = ''
    //console.log(prefix)
    return require(prefix+file)
}
exports.global = (file) => {
    var sys = conf('sys'),
        prefix
    if(sys && sys.global) prefix = sys.global
    else prefix = ''
    return require(prefix+file)
}
//  (系统仅仅规定生成单级不存在的目录)生成目录，存在则不做任何事情
exports.mkdir = (dir) =>{
    if(!fs.existsSync(dir)) fs.mkdirSync(dir)
}
exports.empty = (value) =>{
    if(util.isNullOrUndefined(value)) return true
}
//  写入日志 str,uconsle 内容， 同步启动 consol.log
exports.log = (str,uconsle) =>{
    var cf = conf()
    var rtime = cf.runtime
    var fname = cf.root+cf.log
    if(!fs.existsSync(fname)) fs.mkdirSync(fname)
    fname += '/'+rtime.log
    if(str){
        if(uconsle) console.log(str)
        str += "\r\n"
        return fs.appendFileSync(fname,str)
    }
    return false
}
//  调试输出
exports.fprint = (data) =>{
    var cf = conf()
    var rtime = cf.runtime
    var fname = rtime.basedir+this.date('Y-M-D')+'.'+rtime.debug
    if(util.isObject(data)) data = JSON.stringify(data,null,4)//JSON.stringify(data)
    else if(data){
        data = String(data)
    }
    if(data) fs.appendFileSync(fname,"\r\n"+this.date()+"****************\r\n"+data+"\r\n")
}
//  通过头部获取地址URL
exports.client = (req)=>{
    if(!util.isObject(req)) return {}
    return new Request(req)
}
//  url重定向>>子项目无法获取重定位 2016年9月5日 星期一  http://stackoverflow.com/questions/4062260/nodejs-redirect-url
exports.redirect = (url,res,header)=>{
    if(url && res){
        if(header) header['Location'] = url
        else header = {'Location':url}
        res.writeHead(302,header)
    }    
}
//  读取配置文件
function conf(key){
    var dir = __dirname
    dir = dir.replace('module','config')+'/config.js'
    var data = require(dir)
    if(key){
        if(data[key]) return data[key]
        return ''
    }
    return require(dir)
}
//  模块之间可相互读取
exports.test = ()=>{
    console.log(this)
}
//  服务器的 request 类处理
function Request(req){
    this.source = req
    this.header = req.headers
    //  获取完整的请求 URL
    this.href = function(){
        var hd = this.header
        var src = this.source
        var href = hd.host
        return `http://${href}`+src.url
    }
    //  获取客服端的请求IP
    this.getIp = function(type){
        var ipStr = req.headers['x-forwarded-for'] ||
            req.connection.remoteAddress ||//   ::ffff:1.1.1.116
            req.socket.remoteAddress ||// ::ffff:1.1.1.116
            req.connection.socket.remoteAddress
        var arr = ipStr.split(':')
        type = type || 'IPv4'
        var ret
        var IPv4 = arr[arr.length-1]
        if(type == 'IPv4') ret = IPv4
        else if(type == 'IPv6') ret = ipStr.replace(IPv4,'')
        else ret = ipStr
        return ret
    }
    //  判别设备为移动端/PC端
    this.isMobile = function(){
        var hd = this.header
        var agent = hd['user-agent'].toLowerCase(),
            arr = this.mobileOs.split(','),
            key
        for(var k in arr){
            key = arr[k].toLowerCase()
            if(agent.indexOf(key)>-1) return true
        }
        return false
    }
    this.mobileOs = 'Android,iPhone,iPad,Windows Phone'
    this.pcOs = 'Windows'
}

exports.head = (res,code)=>{
    code = code || 200
    res.writeHead(code,{'Content-Type': 'text/html'})
}